home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
filesyst
/
thsfs.tgz
/
thsfs.tar
/
thsfs
/
dir.c
next >
Wrap
C/C++ Source or Header
|
1994-10-04
|
5KB
|
244 lines
/*************************************************************
* *
* ths Filesystem 04.10.94 V1.1 *
* *
* Thomas Scheuermann ths@ai-lab.fh-furtwangen.de *
* *
*************************************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/mm.h>
#include <linux/locks.h>
#include <linux/fs.h>
#include <linux/malloc.h>
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/bitops.h>
#include "ths.h"
#include "ths_i.h"
int ths_dir_read(struct inode *in, struct file *fp, char *buf, int count)
{
printk("dir_read\n");
return -EISDIR;
}
int ths_readdir(struct inode *in, struct file *fp,struct dirent *eintrag, int count)
{
struct ths_buffer tbf;
struct ths_inode_info *ths_inode;
struct ths_sb_info *ths_sb;
struct ths_dir *dir;
long sektor=0,len,pos1;
int i,j;
unsigned char *data=NULL;
ths_inode = (struct ths_inode_info *)&(in->u.generic_ip);
ths_sb = (struct ths_sb_info *)in->i_sb->u.generic_sbp;
#ifdef DEBUG
printk("readdir : %s : %ld\n",ths_inode->name,in->i_ino);
#endif
len = in->i_size;
pos1 = fp->f_pos;
/*
* . und .. im Rootverzeichnis emulieren
*/
if(in->i_ino==THS_ROOT_INODE)
pos1-=64;
if(pos1<0)
{
j=0;
put_fs_byte('.',j+eintrag->d_name);
j++;
if(pos1==-32)
{
put_fs_byte('.',j+eintrag->d_name);
j++;
}
if(pos1==-64)
put_fs_long(THS_ROOT_INODE,&eintrag->d_ino);
put_fs_byte(0,j+eintrag->d_name);
put_fs_word(j,&eintrag->d_reclen);
fp->f_pos+=32;
return j;
}
while(pos1 < len)
{
if(in->i_ino==THS_ROOT_INODE)
{
sektor = (long)ths_sb->RootStart + (pos1>>9);
if(ths_read_sektor(in->i_sb,sektor, &tbf))
{
printk("Fehler\n");
return -1;
}
}
else
{
if(ths_read_cluster(in->i_sb,ths_inode->Cluster,pos1,&tbf))
{
printk("Fehler\n");
return -1;
}
}
data = tbf.data[(pos1/512)%tbf.sektore];
dir = (struct ths_dir *)&(data[(pos1 & 0x01ff)]);
/*
* Test, ob der Eintrag geloescht wurde oder ob es sich
* um den Namen des Volumes handelt.
*/
if(dir->name[0]==0xe5||(dir->attribut & 0x08))
{
fp->f_pos += 32;
pos1 += 32;
if(in->i_ino==THS_ROOT_INODE)
ths_free_sektor(&tbf);
else
ths_free_cluster(&tbf);
continue;
}
/*
* Daten an den User uebergeben
*/
for(i=0,j=0;i<11;i++)
{
if(i==8 && dir->name[i]!=0x20)
{
put_fs_byte('.',j+eintrag->d_name);
j++;
}
if(dir->name[i]!=0x20)
{
put_fs_byte(dir->name[i],j+eintrag->d_name);
j++;
}
}
put_fs_long(sektor * 16 + ((pos1 & 0x01ff) >>5),&eintrag->d_ino);
put_fs_byte(0,j+eintrag->d_name);
put_fs_word(j,&eintrag->d_reclen);
if(in->i_ino==THS_ROOT_INODE)
ths_free_sektor(&tbf);
else
ths_free_cluster(&tbf);
fp->f_pos += 32;
pos1 += 32;
return j;
}
return 0;
}
int ths_lookup(struct inode *in,const char *name, int l, struct inode **result)
{
struct ths_inode_info *ths_inode;
struct ths_sb_info *ths_sb;
struct ths_dir *dir=NULL;
struct ths_buffer tbf;
long sektor,len,innr;
int addr,i,test;
unsigned char *data=NULL;
sektor = 0;
addr = 0;
ths_inode = (struct ths_inode_info *)&(in->u.generic_ip);
ths_sb = (struct ths_sb_info *)in->i_sb->u.generic_sbp;
#ifdef DEBUG
printk("lookup : %s laenge : %d\n",name,l);
#endif
len = in->i_size;
i=0;
while(i < len)
{
if((i & 0x1ff) ==0)
{
if(in->i_ino==THS_ROOT_INODE)
{
sektor = (long)ths_inode->Cluster + (i>>9);
if(ths_read_sektor(in->i_sb,sektor, &tbf))
{
printk("Fehler\n");
return -1;
}
}
else
{
if(!((i/512)%ths_sb->SektorenProCluster))
{
if(ths_read_cluster(in->i_sb,ths_inode->Cluster,i,&tbf))
{
printk("Fehler\n");
return -1;
}
}
}
data = tbf.data[(i/512)%tbf.sektore];
}
dir = (struct ths_dir *)&(data[(i & 0x01ff)]);
/*
* Namensvergleich
*/
test=vergleich(dir,name,l);
if(name[0]=='.' && l == 1 && in->i_ino == THS_ROOT_INODE)
test = 1;
if(test)
{
innr = tbf.cluster ? (tbf.cluster*tbf.sektore+ths_sb->DatenStart)*16 + ((i&((0x100<<tbf.sektore)-1))>>5) :
tbf.sektnr[0]*16 + ((i&0x1ff)>>5);
if(l==1 && name[0] =='.')
innr = in->i_ino;
if(l==2 && name[0] =='.' && name[1] =='.' && dir->cluster ==0)
innr = THS_ROOT_INODE;
*result = iget(in->i_sb,innr);
if(!*result)
{
iput(in);
if(in->i_ino==THS_ROOT_INODE)
ths_free_sektor(&tbf);
else
ths_free_cluster(&tbf);
return -EACCES;
}
iput(in);
if(in->i_ino==THS_ROOT_INODE)
ths_free_sektor(&tbf);
else
ths_free_cluster(&tbf);
return 0;
}
i+=32;
if((i & 0x1ff) ==0)
{
if(in->i_ino==THS_ROOT_INODE)
ths_free_sektor(&tbf);
else if(!((i/512)%tbf.sektore))
ths_free_cluster(&tbf);
}
}
iput(in);
return -ENOENT;
}